/*
 * Copyright (c) 2011 Jean-Marc Perronne
 * Ensisa, 12 rue des Freres Lumieres, F-68093 Mulhouse cedex
 * All rights reserved.
 *
 * The copyright of this software is owned by Werner Randelshofer. 
 * You may not use, copy or modify this software, except in  
 * accordance with the license agreement you entered into with  
 * Jean-Marc Perronne. For details see accompanying license terms. 
 */

package fr.uha.ensisa.jmp.connexion_3d;


public class Mouse3D
{
	private native int open(int id);
	private native int close(int id);
	private native int buttonsNumber(int id);
	private native int readEvent(int id, Event e);
	private native int readEventOverlapped(int id, Event e);
	private native int ledOn(int id);
	private native int ledOff(int id);
	private native String manufacturerString(int id);
	private native String productString(int id);
	private native boolean isValidDevice(int id);
	private native int isOverLapped(int id);

	private native int usage(int id, Usage usage);
	
	public final static int BAD_PRODUCT_ID	 = -1;
	public final static int OPE_FAILED = -2;
	public final static int JNI_FAILED = -3;
	public final static int OPE_SUCCESS = -4;
	public final static int DEVICE_DISCONNECTED = -5;
	public final static int READ_PENDING  = -6;

	private int productId, mouseId;
	private boolean valid;
	
	public Mouse3D(int mouseId, int productId)
	{
		this.mouseId = mouseId;
		this.productId = productId;
		this.valid = this.isValidDevice(this.mouseId);
	}
	
	public boolean isValid()
	{
		return this.valid;
	}
	
	public void open() throws Mouse3DException
	{
		switch (this.open(this.mouseId))
		{
		case BAD_PRODUCT_ID: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onOpen, Mouse3DException.What.badMouseId);
		case OPE_FAILED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onOpen, Mouse3DException.What.opeFailed);
		case JNI_FAILED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onOpen, Mouse3DException.What.jniFailed);
		case OPE_SUCCESS:break;
		}
	}
	
	public Mouse3DException.What close() 
	{
		switch (this.close(this.mouseId))
		{
		case BAD_PRODUCT_ID: return Mouse3DException.What.badMouseId;
		case OPE_FAILED: return  Mouse3DException.What.opeFailed;
		case JNI_FAILED:return Mouse3DException.What.jniFailed;
		case DEVICE_DISCONNECTED: return Mouse3DException.What.deviceDisconnected;
		default: return Mouse3DException.What.success;
		}
	}
	
	public int buttonsNumber() throws Mouse3DException
	{
		int res = this.buttonsNumber(this.mouseId);
		switch (res)
		{
		case BAD_PRODUCT_ID: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onButtonsNbr, Mouse3DException.What.badMouseId);
		case OPE_FAILED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onButtonsNbr, Mouse3DException.What.opeFailed);
		case JNI_FAILED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onButtonsNbr, Mouse3DException.What.jniFailed);
		case DEVICE_DISCONNECTED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onButtonsNbr, Mouse3DException.What.deviceDisconnected);
		default: return res;
		}
	}
	
	public boolean readEvent(Event e) throws Mouse3DException
	{
			switch (this.readEvent(this.mouseId, e))
			{
				case BAD_PRODUCT_ID: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onRead, Mouse3DException.What.badMouseId);
				case OPE_FAILED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onRead, Mouse3DException.What.opeFailed);
				case JNI_FAILED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onRead, Mouse3DException.What.jniFailed);
				case DEVICE_DISCONNECTED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onRead, Mouse3DException.What.deviceDisconnected);
				case READ_PENDING : return false;
				case OPE_SUCCESS: return true;
			}
			throw new Mouse3DException(this.mouseId, Mouse3DException.When.onRead, Mouse3DException.What.opeFailed);
	}
	
	public boolean readEventOverlapped(Event e) throws Mouse3DException
	{
		switch (this.readEventOverlapped(this.mouseId, e))
		{
		case BAD_PRODUCT_ID: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onRead, Mouse3DException.What.badMouseId);
		case OPE_FAILED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onRead, Mouse3DException.What.opeFailed);
		case JNI_FAILED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onRead, Mouse3DException.What.jniFailed);
		case DEVICE_DISCONNECTED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onRead, Mouse3DException.What.deviceDisconnected);
		case READ_PENDING : return false;
		case OPE_SUCCESS: return true;
		}
		throw new Mouse3DException(this.mouseId, Mouse3DException.When.onRead, Mouse3DException.What.opeFailed);
	}

	
	public void ledOn() throws Mouse3DException
	{
		switch (this.ledOn(this.mouseId))
		{
		case BAD_PRODUCT_ID: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onLedOn, Mouse3DException.What.badMouseId);
		case OPE_FAILED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onLedOn, Mouse3DException.What.opeFailed);
		case JNI_FAILED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onLedOn, Mouse3DException.What.jniFailed);
		case DEVICE_DISCONNECTED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onLedOn, Mouse3DException.What.deviceDisconnected);
		case OPE_SUCCESS:break;
		}
	}
	
	public void ledOff() throws Mouse3DException
	{
		switch (this.ledOff(this.mouseId))
		{
		case BAD_PRODUCT_ID: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onLedOff, Mouse3DException.What.badMouseId);
		case OPE_FAILED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onLedOff, Mouse3DException.What.opeFailed);
		case JNI_FAILED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onLedOff, Mouse3DException.What.jniFailed);
		case DEVICE_DISCONNECTED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onLedOff, Mouse3DException.What.deviceDisconnected);
		case OPE_SUCCESS:break;
		}
	}
	
	public Usage usage() throws Mouse3DException
	{
		Usage usage = new Usage();
		switch (this.usage(this.mouseId, usage))
		{
		case BAD_PRODUCT_ID: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onUsage, Mouse3DException.What.badMouseId);
		case OPE_FAILED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onUsage, Mouse3DException.What.opeFailed);
		case JNI_FAILED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onUsage, Mouse3DException.What.jniFailed);
		case DEVICE_DISCONNECTED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onUsage, Mouse3DException.What.deviceDisconnected);
		case OPE_SUCCESS: break;
		}
		return usage;
	}
	
	public boolean isOverlapped()throws Mouse3DException
	{
		int res = this.isOverLapped(this.mouseId);
		switch (res)
		{
		case BAD_PRODUCT_ID: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onIsOverlapped, Mouse3DException.What.badMouseId);
		case OPE_FAILED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onIsOverlapped, Mouse3DException.What.opeFailed);
		case JNI_FAILED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onIsOverlapped, Mouse3DException.What.jniFailed);
		case DEVICE_DISCONNECTED: throw new Mouse3DException(this.mouseId, Mouse3DException.When.onIsOverlapped, Mouse3DException.What.deviceDisconnected);
		default: return (res != 0);
		}
	}
	
	public String manufacturerString() throws Mouse3DException
	{
		String res = this.manufacturerString(this.mouseId);
		if (res.equals("BAD_PRODUCT_ID"))  throw new Mouse3DException(this.mouseId, Mouse3DException.When.onManufacturerString, Mouse3DException.What.badMouseId);
		if (res.equals("DEVICE_DISCONNECTED")) throw new Mouse3DException(this.mouseId, Mouse3DException.When.onManufacturerString, Mouse3DException.What.deviceDisconnected);
		if (res.equals(""))  throw new Mouse3DException(this.mouseId, Mouse3DException.When.onManufacturerString, Mouse3DException.What.opeFailed);
		return res;
	}
	
	public String productString() throws Mouse3DException
	{
		String res = this.productString(this.mouseId);
		if (res.equals("BAD_PRODUCT_ID"))  throw new Mouse3DException(this.mouseId, Mouse3DException.When.onProductString, Mouse3DException.What.badMouseId);
		if (res.equals("DEVICE_DISCONNECTED")) throw new Mouse3DException(this.mouseId, Mouse3DException.When.onProductString, Mouse3DException.What.deviceDisconnected);
		if (res.equals(""))  throw new Mouse3DException(this.mouseId, Mouse3DException.When.onManufacturerString, Mouse3DException.What.opeFailed);
		return res;
	}

	public int productId()
	{
		return this.productId;
	}
	
	public int mouseId()
	{
		return this.mouseId;
	}
}